home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / comm / bbs / s342q16.lha / 2ndfmt.c next >
C/C++ Source or Header  |  1996-08-29  |  7KB  |  341 lines

  1. /*
  2.  *                2ndfmt.C
  3.  *
  4.  * Creates a pre-processed secondary file from raw input.
  5.  */
  6.  
  7. /*
  8.  *                History
  9.  *
  10.  * 90May21  HAW V1 Created.
  11.  */
  12.  
  13. /*
  14.  *                Contents
  15.  *
  16.  *    main()            main manager
  17.  *    InitData()        initializes the data structures
  18.  *    SysCheck()        list search function
  19.  *    SysCmp()        list sorting function
  20.  *    EatDomainLine()        eats a line from the map file
  21.  *    GetDynamic()        malloc bottleneck
  22.  *    ShowArguments()        usage
  23.  *    WriteCompressed()    manages writing out the compressed map
  24.  *    WriteSystems()        work fn to write out map info
  25.  */
  26.  
  27. #include "2ndfmt.h"
  28. #include "slist.h"
  29.  
  30. void Motorola32ToIntel(UNS_32 *val);
  31.  
  32. void crashout(char *str);
  33.  
  34. void crashout(str)
  35. char *str;
  36.   {
  37.   exit(printf(str));
  38.  
  39.   }
  40.  
  41. void Motorola32ToIntel(UNS_32 *val)
  42.   {
  43.   unsigned long temp;
  44.   temp = *val;
  45.   *val = ((ULONG)(temp & 0xff) << 24) + ((ULONG)(temp & 0xff00) << 8) +
  46.   ((ULONG)(temp & 0xff0000) >> 8) + ((ULONG)(temp &0xff000000) >> 24);
  47.  
  48.   }
  49.  
  50.  
  51. #define TRUE        1
  52. #define FALSE        0
  53.  
  54. typedef struct {
  55.     long ByteCount;
  56.     SListBase SysList;
  57. } Bucket;
  58. Bucket Buckets[BUCKETCOUNT];        /* 0 .. 9, A .. Z   */
  59.  
  60. typedef struct {
  61.     char DupFlag;
  62.     char *Domain;        /* domain name */
  63.     char *SysName;
  64.     char *RealName;        /* if SysName is an alias, this is the real name */
  65. } ASystem;
  66.  
  67. extern FILE *upfd;
  68.  
  69. void *SysCheck(), *EatDomainLine();
  70. int  SysCmp();
  71. char version[90];
  72.  
  73. /* just so we can automate reading the file */
  74. SListBase Dummy = { NULL, NULL, NULL, NULL, EatDomainLine };
  75.  
  76. JumpInfo JumpTable[BUCKETCOUNT];
  77.  
  78. /*
  79.  * Initial Format
  80.  *
  81.  * The initial format of the input file is a collection of "domain" records.
  82.  * Each record begins with the line ".domain <domainname>".  Each following
  83.  * non-blank line designates a system within that domain until EOF or the
  84.  * next line of format ".domain <domainname>".
  85.  *
  86.  * Each line designating a system is generically:
  87.  *
  88.  * <system name>[:<real name>]
  89.  *
  90.  * Real name is only of use when defining a common alias for a system.  For
  91.  * example,
  92.  *
  93.  * Test System : C-86 Test System
  94.  *
  95.  * would make a lot of sense.
  96.  */
  97.  
  98. /*
  99.  * Final Format
  100.  *
  101.  * Each line will look generically like this:
  102.  *
  103.  * [flag byte]<system><tab><domain>[<tab><real name>]<\n>
  104.  *
  105.  * In English, an entry is composed of an optional flag byte, followed by
  106.  * the system name and its domain separated by a TAB, optionally followed
  107.  * by the real system name (again separated by a TAB) if the name is an
  108.  * alias for someone else.
  109.  *
  110.  * The optional flag byte is distinguishable by its value, which will be
  111.  * non-printing (!isprint(x)).  Flag byte values will be defined as needed.
  112.  * Currently, the list of flag values (see 2ndFmt.h, too) is limited to
  113.  * this:
  114.  *
  115.  * DUPLICATE - 0x01, this means there is more than one system by this name
  116.  * in the list.  Makes processing a bit easier by main program.
  117.  *
  118.  */
  119.  
  120. extern char      *READ_TEXT, *WRITE_ANY;
  121.  
  122. FILE *fd;
  123.  
  124. void ShowArguments(void);
  125. void InitData(void);
  126. void WriteCompressed(void);
  127.  
  128. /*
  129.  * main()
  130.  *
  131.  * This is the main manager for routemap eater.
  132.  */
  133. int main(int , char **);
  134.  
  135. int main(argc, argv)
  136. int  argc;
  137. char **argv;
  138. {
  139.  
  140.     printf("2ndFmt V1.0\nSecondary List Processor\n%s\n", FMT_COPYRIGHT);
  141.  
  142.     if (argc != 3) {
  143.         ShowArguments();
  144.         exit(1);
  145.     }
  146.  
  147.     InitData();
  148.  
  149.     if ((fd = fopen(argv[1], READ_TEXT)) == NULL)
  150.     exit(printf("Could not open %s.\n", argv[1]));
  151.  
  152.     GetAString(version, sizeof version, fd);
  153.  
  154.     MakeList(&Dummy, "", fd);    /* eat designated file */
  155.  
  156.     if ((fd = fopen(argv[2], WRITE_ANY)) == NULL)
  157.         exit(printf("Couldn't open output file %s.", argv[2]));
  158.  
  159.     WriteCompressed();
  160.  
  161.     return 0;
  162. }
  163.  
  164. /*
  165.  * InitData()
  166.  *
  167.  * This function initializes the data structures.
  168.  */
  169. void InitData()
  170. {
  171.     int rover;
  172.  
  173.     for (rover = 0; rover < BUCKETCOUNT; rover++) {
  174.         Buckets[rover].ByteCount = 0l;
  175.         InitListValues(&Buckets[rover].SysList, SysCheck, SysCmp,
  176.                                 NULL, NULL);
  177.     }
  178. }
  179.  
  180. /*
  181.  * SysCheck()
  182.  *
  183.  * This is a list search function.
  184.  */
  185. void *SysCheck(ASystem *s, char *str)
  186. {
  187.     return (stricmp(s->SysName, str) == 0) ? s : NULL;
  188. }
  189.  
  190. /*
  191.  * SysCmp()
  192.  *
  193.  * This is a sorting function for the list.
  194.  */
  195. int  SysCmp(ASystem *s, ASystem *t)
  196. {
  197.     if (stricmp(s->SysName, t->SysName) == 0) {
  198.         if (s->DupFlag) return -1;    /* duplicate flag comes first */
  199.         if (t->DupFlag) return 1;
  200.     }
  201.     return (stricmp(s->SysName, t->SysName));
  202. }
  203.  
  204. #define DOMAIN        0
  205. #define SYSTEM        1
  206.  
  207. char MapState = DOMAIN;
  208. char *CurDomain;
  209. /*
  210.  * EatDomainLine()
  211.  *
  212.  * This will eat a line from the map file and return an appropriately
  213.  * initialized structure.
  214.  */
  215. void *EatDomainLine(char *line)
  216. {
  217.     char *c, *d;
  218.     ASystem *data;
  219.     int bucket;
  220.  
  221.     if ((c = strchr(line, '%')) != NULL)    *c = 0;
  222.  
  223.     if (strncmp(line, ".domain", 7) == 0) {
  224.         if ((c = strchr(line, ' ')) == NULL || strlen(c) < 2) {
  225.             printf("Bad domain formation (no space).\n");
  226.             return NULL;
  227.         }
  228.         if ((d = strchr(c + 1, ' ')) != NULL) *d = 0;
  229.         CurDomain = strdup(c + 1);
  230.         MapState = SYSTEM;
  231.         return NULL;
  232.     }
  233.  
  234.     if (MapState == SYSTEM && strlen(line) > 2) {
  235.         data = GetDynamic(sizeof *data);
  236.         if ((c = strchr(line, ':')) != NULL)
  237.             *c++ = 0;
  238.  
  239.         NormStr(line);        /* clean up string */
  240.         if (!isalpha(*line) && !isdigit(*line)) {
  241.             printf("ERROR: '-%s-' is NOT a valid system name.\n",
  242.                             line);
  243.             return NULL;
  244.         }
  245.  
  246.         data->SysName = strdup(line);
  247.         if (c == NULL)
  248.             data->RealName = NULL;
  249.         else {
  250.             NormStr(c);
  251.             data->RealName = strdup(c);
  252.         }
  253.         data->Domain = CurDomain;
  254.  
  255.         bucket = (isdigit(line[0])) ?    line[0] - '0' :
  256.                         toupper(line[0]) - 'A' + 10;
  257.         data->DupFlag = (SearchList(&Buckets[bucket].SysList, line) != NULL);
  258.         AddData(&Buckets[bucket].SysList, data, NULL, FALSE);
  259.         Buckets[bucket].ByteCount += strlen(data->SysName) + 1;
  260.         Buckets[bucket].ByteCount += strlen(data->Domain) + 1;
  261.         if (data->RealName != NULL)
  262.             Buckets[bucket].ByteCount += strlen(data->RealName) + 1;
  263.         if (data->DupFlag) {
  264.             printf("NOTE: Duplicate found for name %s.\n", data->SysName);
  265.             Buckets[bucket].ByteCount++;
  266.         }
  267.     }
  268.     return NULL;
  269. }
  270.  
  271.  
  272. /*
  273.  * ShowArguments()
  274.  *
  275.  * This function will show the usage of this utility to the user.
  276.  */
  277. void ShowArguments(void)
  278. {
  279.     printf("Usage: 2ndfmt <input filename> <output filename>");
  280. }
  281.  
  282. /*
  283.  * WriteCompressed()
  284.  *
  285.  * This function manages writing out the compressed map.
  286.  */
  287. void WriteCompressed(void)
  288. {
  289.     long count = 0l;
  290.     char vers;
  291.     int rover;
  292.     void WriteSystems();
  293.  
  294.     vers = TABLE_VERS;
  295.  
  296.     fwrite(version, VERS_SIZE, 1, fd);
  297.     fwrite(&vers, sizeof vers, 1, fd);
  298.     count = VERS_SIZE + sizeof JumpTable + sizeof vers;
  299.  
  300. #ifdef IS_MOTOROLA
  301.     for (rover = 0; rover < BUCKETCOUNT; rover++)
  302.         Motorola32ToIntel(&JumpTable[rover].offset);
  303. #endif
  304.  
  305.     /* write out jump table */
  306.     for (rover = 0; rover < BUCKETCOUNT; rover++) {
  307.         JumpTable[rover].offset = count;
  308.         count += Buckets[rover].ByteCount;
  309.     }
  310.  
  311. #ifdef IS_MOTOROLA
  312.     for (rover = 0; rover < BUCKETCOUNT; rover++)
  313.         Motorola32ToIntel(&JumpTable[rover].offset);
  314. #endif
  315.  
  316.     fwrite(JumpTable, sizeof JumpTable, 1, fd);
  317.  
  318.     for (rover = 0; rover < BUCKETCOUNT; rover++)
  319.         RunList(&Buckets[rover].SysList, WriteSystems);
  320.  
  321.     fprintf(fd, "\n");    /* marks EOF - eliminate noise */
  322.  
  323.     fclose(fd);
  324. }
  325.  
  326. /*
  327.  * WriteSystems()
  328.  *
  329.  * This is the work fn to write out the information.
  330.  */
  331. void WriteSystems(ASystem *data)
  332. {
  333.     if (data->DupFlag)
  334.         fprintf(fd, "%c", DUP);
  335.     fprintf(fd, "%s\t%s", data->SysName, data->Domain);
  336.     if (data->RealName != NULL)
  337.         fprintf(fd, "\t%s", data->RealName);
  338.     fprintf(fd, "\n");
  339. }
  340.  
  341.